#include <limits.h>

typedef unsigned int uint;
typedef unsigned long ulong;
typedef long long longlong;
typedef unsigned long long ulonglong;
// using 'byte' causes compilation problems on Windows
typedef signed char sbyte;
typedef unsigned char ubyte;
typedef unsigned short ushort;

typedef void* pointer;
typedef long double longdouble;
 
#define sint8_MAX 127
#define sint8_MIN -128
#define uint8_MAX 255
#define uint8_MIN 0

#define sint16_MAX 32767
#define sint16_MIN -32768
#define uint16_MAX 65535
#define uint16_MIN 0

#define sint32_MAX 2147483647
#define sint32_MIN (-2147483647-1)
#define minus11 -1
#define uint32_MAX 4294967295U
#define uint32_MIN 0

#define sint64_MAX 9223372036854775807LL
#define sint64_MIN -9223372036854775807LL-1
#define uint64_MAX 0xffffffffffffffffLL
#define uint64_MIN 0

#define int_MAX INT_MAX
#define int_MIN INT_MIN

#if SCHAR_MAX == sint8_MAX
typedef signed char sint8;
typedef unsigned char uint8;
#define ffi_type_sbyte ffi_type_sint8
#define ffi_type_ubyte ffi_type_uint8
#else
 #error "cannot define sint8/uint8"
#endif

#if SHRT_MAX == sint16_MAX
typedef signed short sint16;
typedef unsigned short uint16;
#define ffi_type_sshort ffi_type_sint16
#define ffi_type_ushort ffi_type_uint16
#else
 #error "cannot define sint16/uint16"
#endif

#if INT_MAX == sint32_MAX
typedef signed int sint32;
typedef unsigned int uint32;
#else
 #error "cannot define sint32/uint32"
#endif

// ffi.h defines ulong/slong as 64bit integers (why?)
// we want ulong/slong to correspond to the usual C long
#if LONG_MAX == sint32_MAX
#undef ffi_type_ulong
#undef ffi_type_slong
#define ffi_type_ulong ffi_type_uint32
#define ffi_type_slong ffi_type_sint32
#elif LONG_MAX == sint64_MAX
#define ffi_type_ulong ffi_type_uint64
#define ffi_type_slong ffi_type_sint64
#else
 #error "cannot define ffi_type_ulong/slong"
#endif

#ifndef LONG_LONG_MAX
# ifdef LLONG_MAX
#  define LONG_LONG_MAX LLONG_MAX
# else
#  ifdef __GNUC__
#   define LONG_LONG_MAX __LONG_LONG_MAX__
#  endif
#  ifdef _MSC_VER
#   define LONG_LONG_MAX _I64_MAX
#  endif
# endif
#endif

#if LONG_LONG_MAX == sint64_MAX
typedef signed long long sint64;
typedef unsigned long long uint64;
#define ffi_type_longlong ffi_type_sint64
#define ffi_type_ulonglong ffi_type_uint64
#else
 #error "cannot define sint64/uint64"
#endif
